#pragma once

/* 在这里建立user的ODB映射 */

#include <string>
#include <cstddef> // std::size_t
#include <odb/nullable.hxx>
#include <odb/core.hxx>

namespace ChatSystem
{
    #pragma db object table("user")
    //用户表映射的对象
    class User
    {
    public:
        User()
        {}
        ~User()
        {}

        //用户名---新增用户---新增的信息是用户ID、昵称、密码
        User(const std::string& uid, const std::string& nickname, const std::string& password)
        :_user_id(uid), _nickname(nickname), _password(password)
        {}
        //手机号---新增用户---新增的信息是用户ID、手机号
        User(const std::string& uid, const std::string& phone)
        :_user_id(uid), _nickname(uid), _phone(phone)
        {}

        //获取用户ID
        std::string user_id() const
        {
            return _user_id;
        }
        //获取用户ID
        std::string user_id()
        {
            return _user_id;
        }
        //修改用户ID
        void user_id(const std::string& uid)
        {
            _user_id = uid;
        }
        //获取昵称
        std::string nickname()const
        {
            if(!_nickname)
            {
                return std::string();
            }
            return *_nickname;
        }
        std::string nickname()
        {
            if(!_nickname)
            {
                return std::string();
            }
            return *_nickname;
        }
        //修改昵称
        void nickname(const std::string& val)
        {
            _nickname = val;
        }

        //获取签名
        std::string description()const
        {
            if(!_description)
            {
                return std::string();
            }
            return *_description;
        }
        std::string description()
        {
            if(!_description)
            {
                return std::string();
            }
            return *_description;
        }
        //修改签名
        void description(const std::string& val)
        {
            _description = val;
        }

        //获取密码
        std::string password()const
        {
            if(!_password)
            {
                return std::string();
            }
            return *_password;
        }
        std::string password()
        {
            if(!_password)
            {
                return std::string();
            }
            return *_password;
        }
        //修改密码
        void password(const std::string& val)
        {
            _password = val;
        }

        //获取手机号
        std::string phone()const
        {
            if(!_phone)
            {
                return std::string();
            }
            return *_phone;
        }
        std::string phone()
        {
            if(!_phone)
            {
                return std::string();
            }
            return *_phone;
        }
        //修改手机号
        void phone(const std::string& val)
        {
            _phone = val;
        }

        //获取头像文件ID
        std::string avatar_id()const
        {
            if(!_avatar_id)
            {
                return std::string();
            }
            return *_avatar_id;
        }
        std::string avatar_id()
        {
            if(!_avatar_id)
            {
                return std::string();
            }
            return *_avatar_id;
        }
        //修改头像文件ID
        void avatar_id(const std::string& val)
        {
            _avatar_id = val;
        }


    private:
        friend class odb::access;   //建立友元关系，以便odb框架来访问我们的私有成员
        #pragma db id auto
        unsigned long _id;  //主键---这个只能保证同一主机上的用户之间不能重复，而不能保证不同主机数据库上id的唯一性
        #pragma db type("varchar(255)") index unique   //设置为唯一键索引，服务器之间通信使用的是用户ID 和 用户搜索的时候，会通过这个索引进行检索
        std::string _user_id;   //用户ID，将用户ID设置为string类型是为了防止不同主机之间用户ID的重复
        //用户昵称不一定存在，因为可以通过手机号来注册用户，而手机号注册用户是不需要设置昵称的，所以将这个字段设置为可以为空的字段；
        //用户昵称是唯一的
        #pragma db type("varchar(64)") index unique
        odb::nullable<std::string> _nickname;       //用户昵称---不一定存在，可以为空的字段，使用odb::nullable来管理
        odb::nullable<std::string> _description;    //用户签名---不一定存在，可以为空的字段，使用odb::nullable来管理
        //通过手机号注册的用户没有设置密码，每次都是通过手机号来登录的，所以也是一个不一定存在的字段
        #pragma db type("varchar(64)")
        odb::nullable<std::string> _password;       //登录密码---不一定存在，可以为空的字段，使用odb::nullable来管理
        //通过用户名注册的用户是没有绑定手机号的，所以也是一个不一定存在的字段
        #pragma db index  //设置为普通索引，用户搜索的时候，会通过这个索引进行检索
        #pragma db type("varchar(64)") index unique
        odb::nullable<std::string> _phone;  //绑定手机号---不一定存在，可以为空的字段，使用odb::nullable来管理
        #pragma db type("varchar(64)") unique
        odb::nullable<std::string> _avatar_id;  //用户头像文件ID---不一定存在，可以为空的字段，使用odb::nullable来管理
    };

}

//odb 编译：odb -d mysql --generate-query --generate-schema --profile boost/date-time user.hxx